""""""
"""上下文管理器
一个类只要实现了__enter__()和__exit__()这个两个方法，通过该类创建的对象我们就称之为上下文管理器。
上下文管理器可以使用 with 语句，with语句之所以这么强大，背后是由上下文管理器做支撑的，也就是说刚才使用 open 函数创建的文件对象就是就是一个上下文管理器对象。
"""

"""
自定义上下文管理器类,模拟文件操作:
定义一个File类，实现 __enter__() 和 __exit__()方法，然后使用 with 语句来完成操作文件
"""
class File(object):

    # 初始化方法
    def __init__(self, file_name, file_model):
        # 定义变量保存文件名和打开模式
        self.file_name = file_name
        self.file_model = file_model

    # 上文方法
    def __enter__(self):
        print("进入上文方法")
        # 返回文件资源
        self.file = open(self.file_name,self.file_model)
        return self.file

    # 下文方法
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("进入下文方法")
        self.file.close()


if __name__ == '__main__':

    # 使用with管理文件
    with File("1.txt", "r") as file:
        file_data = file.read()
        print(file_data)

"""
假如想要让一个函数成为上下文管理器，Python 还提供了一个 @contextmanager 的装饰器，更进一步简化了上下文管理器的实现方式。
通过 yield 将函数分割成两部分，yield 上面的语句在 __enter__ 方法中执行，yield 下面的语句在 __exit__ 方法中执行，
紧跟在 yield 后面的参数是函数的返回值。
"""
# 导入装饰器
from contextlib import contextmanager


# 装饰器装饰函数，让其称为一个上下文管理器对象
@contextmanager
def my_open(path, mode):
    try:
        print("上文")
        f = open(path, mode)
        yield f
    except Exception as e:
        f.close()
        print("下文")

# 使用with语句
with my_open('out.txt', 'w') as f:
    f.write("hello , the simplest context manager")
